package rpc.health;

import org.redisson.Redisson;
import org.redisson.api.RLongAdder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import rpc.client.RpcClientHandler;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;
import java.util.Map;

public class HealthPluginImpl implements HealthPlugin{

    @Autowired
    Map<InetSocketAddress, RpcClientHandler> subHealthAddress;
    @Autowired
    Map<InetSocketAddress, RpcClientHandler> unHealthAddress;
    @Autowired
    Map<InetSocketAddress, RpcClientHandler> healthAddress;
    @Autowired
    Map<InetSocketAddress, RpcClientHandler> connectedServerNodes;

    @Autowired
    Redisson redisson;

    @Override
    public void success(InetSocketAddress address) {
        String key = buildKey(address, "success");
        RLongAdder longAdder = redisson.getLongAdder(key);
        longAdder.increment();
    }

    @Scheduled
    @Override
    public void check() {
        connectedServerNodes.keySet().forEach(address -> {
            String successKey = buildKey(address, "success");
            String causeKey = buildKey(address, "cause");
            RLongAdder successLongAdder = redisson.getLongAdder(successKey);
            RLongAdder causeLongAdder = redisson.getLongAdder(causeKey);

            double percent = (double) successLongAdder.sum() / (successLongAdder.sum() + causeLongAdder.sum());
            if (percent < 0.3){
                unHealthAddress.put(address, healthAddress.remove(address));
            }else if (percent < 0.8 && percent > 0.5){
                subHealthAddress.put(address, healthAddress.remove(address));
            }else if (percent > 0.9){
                healthAddress.put(address, connectedServerNodes.get(address));
            }
        });
    }


    @Override
    public void cause(InetSocketAddress address, Throwable throwable) {
        String key = buildKey(address, "cause");
        RLongAdder longAdder = redisson.getLongAdder(key);
        longAdder.decrement();

    }

    private String buildKey(InetSocketAddress address, String action){
        return address.getHostName() + ":" + address.getPort() + ":" + action;
    }
}
